package br.inf.solutions.apresentacoes.ssp.control.bulletin;

import java.text.SimpleDateFormat;
import java.util.List;

import br.com.vexillum.util.HibernateUtils;
import br.com.vexillum.util.Return;
import br.com.vexillum.util.SpringFactory;
import br.inf.solutions.apresentacoes.ssp.control.PublicationController;
import br.inf.solutions.apresentacoes.ssp.control.SearchPersonController;
import br.inf.solutions.apresentacoes.ssp.model.Publication;
import br.inf.solutions.apresentacoes.ssp.model.bulletin.BulletinAwaitItens;
import br.inf.solutions.apresentacoes.ssp.model.bulletin.BulletinItem;
import br.inf.solutions.apresentacoes.ssp.model.bulletin.BulletinTopics;
import br.inf.solutions.apresentacoes.ssp.model.interfaces.IBulletinItem;

public abstract class BaseItensBulletinController<E extends BulletinItem> extends SearchPersonController<E> {

	public BaseItensBulletinController(Class<E> classEntity) {
		super(classEntity);
	}

	@Override
	public Return save() {
		if(!(getEntity() instanceof IBulletinItem)){
			throw new IllegalArgumentException("A entidade deve implementar a classe IBulletinItem!");
		}
		
		getEntity().setPublication(getEntity().getDefaultPublication());
		getEntity().setTextItem(constructBaseTextItem(data.get("action")));
		
		Return ret = new Return(true);
		
		if(ret.isValid()){
			ret = saveAwaitItem();
		}
		
		return ret;
	}
	
	@SuppressWarnings("unchecked")
	public Return retification(){
		getEntity().setPublication(getEntity().getDefaultPublication());
		getEntity().setTextItem(constructBaseTextItem(data.get("action")));
		
		Return ret = new Return(true);
		
//		ret = modifyItemRetification();
		getEntity().setId(null);
		getEntity().setBulletin(null);
		getEntity().setRectifiedItem((E) getData().get("itemToRetificate"));
		
		ret = saveAwaitItem();
		
		return ret;
	}
	
	private Return saveAwaitItem(){
		BulletinAwaitItens item = new BulletinAwaitItens((BulletinItem) getEntity(), (BulletinTopics) HibernateUtils.materializeProxy(getEntity().getBulletinTopic()));
		
		BulletinAwaitItensController controller = SpringFactory.getController("bulletinAwaitItensController", BulletinAwaitItensController.class, null);
		controller.setEntity(item);
		
		return controller.save();
	}
	
	private Return modifyItemRetification(E item) {
		item.setPublication(getReticatedPublication());
		
		return update(item);
	}

	private boolean haveRetification() {
		return getData().get("retification") == null ? false : (boolean) getData().get("retification");
	}
	
	protected Publication getDefaultPublication(){
		PublicationController controller = SpringFactory.getController("publicationController", PublicationController.class, null);
		return controller.getDefaultPuplication();
	}
	
	protected Publication getPublicatedPublication(){
		PublicationController controller = SpringFactory.getController("publicationController", PublicationController.class, null);
		return controller.getPublicatedPuplication();
	}
	
	protected Publication getReticatedPublication(){
		PublicationController controller = SpringFactory.getController("publicationController", PublicationController.class, null);
		return controller.getRetificatedPuplication();
	}
	
	@SuppressWarnings("unchecked")
	protected String constructBaseTextItem(Object modifer){
		String text = "";
		if(haveRetification()){
			E item = (E) getData().get("itemToRetificate");
			text += "Retifico o item abaixo, publicado no boletim " + item.getBulletin().getNumberBulletin() + "/" + item.getBulletin().getYearBulletin() + " - " 
					+ new SimpleDateFormat("dd/MM/yyyy").format(item.getBulletin().getDateBulletin()) + ":\n\n"
					+ item.getTextItem() + "\n\n"
					+ "Retificado para:\n\n";
		}
		text += constructTextItem(modifer);
		return text;
	}
	
	protected abstract String constructTextItem(Object modifer);
	
	@SuppressWarnings("unchecked")
	public Return afterPublicate(){
		if(getEntity().getRectifiedItem() != null){
			modifyItemRetification((E) getEntity().getRectifiedItem());
		}
		return new Return(true);
	}
	
	public List<E> getNotPublicatedItens(){
		return getNotPublicatedItens(null);
	}
	
	@SuppressWarnings("unchecked")
	public List<E> getNotPublicatedItens(Long idBulletin){
		String complement;
		if(idBulletin != null){
			complement = "publication = " + getPublicatedPublication().getId() + " AND bulletin = " + idBulletin;
		} else {
			complement = "publication = " + getDefaultPublication().getId();
		}
		String sql = "FROM " + classEntity.getSimpleName() + " WHERE " + complement;
		getData().put("sql", sql);
		return (List<E>) searchByHQL().getList();
	}
}
